package com.teradata.feedProc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedReader;
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

import com.teradata.feedProc.beans.FeedInfo;
import com.teradata.feedProc.beans.FieldInfo;
import com.teradata.feedProc.enums.FileFormatType;

public class TdmFileTransformService {

	public void processFeed(final String strFeedName) {
		// run the query to get Feed info object
		// run the query to get the field info object
		// load file
		// create iterator over file
		// iterate over file: one line at a time - parse columns and transform
		// dates as needed - write data to output file
	}

	/**
	 * The main method. After iterating through each line in the file, given by
	 * the source input in argv, the information that was processed is written
	 * out to the target file, with any bad information being written to the bad
	 * target file.
	 * 
	 * @param argv
	 *            The input arguments given at runtime. These are <userID>
	 *            <password> <database URL> <feedname> <isQuoted> <source>
	 *            <target> <bad target> <feedKey>
	 */
	public static void main(final String[] argv) {
		System.setProperty("java.net.preferIPv4Addresses", "true");
		// Check command line arguments provided
		if (argv.length < 9 && argv.length > 10) {
			System.err
					.println("Incorrect usage. Use: jar <userID> <password> <database URL> <feedname> <isQuoted> <source> <target> <bad target> <dbname> <feedKey>");
			System.exit(1);
		}
		String params[] = null;
		File file = new File("resources/test.txt");
		try {
			BufferedReader in = new BufferedReader(new FileReader(file));
			 params = in.readLine().split(" ");
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		// source and target file names
		final String userID = params[0];
		String password = params[1];
		if(password.equals("''")) {
			password = "";
		}
		final String dbURL = params[2];
		final String feedName = params[3];
		boolean bIsQuoted;
		String quoted = "";
		if (params[4].equals("N")) {
			bIsQuoted = false;
		} else {
			bIsQuoted = true;
			quoted = params[4];
			System.out.println("String delim value: " + quoted);
		}

		final String sourceFile = params[5];
		final String targetFile = params[6];
		final String badTargetFile = params[7];
		final String dbName = params[8];
		String feedKey = null;
		Boolean ID = false;

		if (params.length == 10) {
			feedKey = params[9];
			ID = true;
		}
		boolean isChecked = false;
		File finalTarget = new File(targetFile);
		File badFinalTarget = new File(badTargetFile);
		BufferedWriter out = null;
		BufferedWriter badOut = null;
		FeedInfo feedInfo = null;
		List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
		Connection conn = null;
		System.out.println("Establishing connection to " + dbURL + " as user " + userID);
		
		conn = DBUtils.createConnection(dbURL, userID, password);
		if (conn != null) {
			feedInfo = DBUtils.getFeedInfo(conn, feedName, dbName, sourceFile, targetFile);
			feedInfo.setbIsQuoted(bIsQuoted);
			fieldInfoList = DBUtils.getFieldInfo(conn, feedInfo);

			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		} else {
			System.out.println("Unable to connect to database.");
			System.exit(1);
		}

		try {
			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(finalTarget), "ISO-8859-1"));
			badOut = new BufferedWriter(new FileWriter(badFinalTarget));
		} catch (Exception e) {
			System.out.println("Could not open the target file " + e.getMessage());
			System.exit(1);
		}

		// iterate over file using FeedInfo and FieldInfo objects to parse
		// each
		// line.
		try {
			FileIterator fileIterator = new FileIterator(feedInfo, fieldInfoList);
			int iLineCnt = 1;
			boolean endsWith = false;
			while (fileIterator.hasMoreLines()) {
				final FileLine fileLine = fileIterator.getNextLine();
				if (fileLine.getLineText() != null) {
					if (!isChecked) {
						fileLine.fileCheck(ID);
						isChecked = true;
					}

					if (feedInfo.getFormatType().equals(FileFormatType.D)) {
						String last = String.valueOf(fileLine.getLineText().charAt(fileLine.getLineText().length() - 1));

						if (last.equals(feedInfo.getDelimiterType().getValue().concat("(?=([^\"]*\"[^\"]*\")*[^\"]*$)")) || last.equals("|")
								|| last.equals(Character.toString((char) 0x1)) || last.equals(Character.toString((char) 0x9)) || last.equals(Character.toString((char) 0x20))) {
							endsWith = true;
						}
					}
					try {
						for (String string : fileLine.getDates(ID, quoted, feedKey, iLineCnt, dbURL, userID, password)) {
							// If a date has been invalidated, the line to
							// be
							// printed to the bad dates file
							// will start with "BAD"
							if (!string.startsWith("BAD")) {
								if (feedInfo.getFormatType().equals(FileFormatType.D)) {
									if (endsWith) {
										for (int i = 0; i < string.length(); i++) {
											out.write(string.charAt(i));
										}
									} else {
										for (int i = 0; i < string.length() - 1; i++) {
											out.write(string.charAt(i));
											out.flush();
										}
									}
								} else {
									for (int i = 0; i < string.length(); i++) {
										out.write(string.charAt(i));
									}
								}
								// writes a new line after streaming all the
								// characters from the record
								out.newLine();
								out.flush();
							} else {
								// Substring the line from the fourth
								// element to get rid of "BAD"
								String writeLine = string.substring(3);
								badOut.write(writeLine);
								badOut.newLine();
							}
						}
						iLineCnt++;
					} catch (Exception ee) {
						System.out.println("Hit exception. " + ee);
					}
				}
			}
			if (conn != null) {
				DBUtils.closeConnection(conn);
			}
			out.close();
			badOut.close();
			System.out.println("Succesfully processed file with line count:" + (iLineCnt - 1));

		} catch (Exception e) {
			System.out.println("Hit exception. " + e.getMessage());
			System.exit(1);
		}
	}
}